﻿Imports System.Threading
Imports System.Threading.Tasks

Public Class DisplayTimer
	Public tokenSource As CancellationTokenSource
	Public task As Task
	Public action As System.Action
	Private _Interval As Double
	Private _IntervalTicks As Long
	Public Shared stopwatch As New Stopwatch
	Public Running As Boolean = False
	Public Counter As ULong = 0

	Public Sub New(ByVal action As System.Action, Optional Interval As Long = 100)
		Me.action = action
		Me.Interval = Interval
		stopwatch.Start()

	End Sub

	Public Sub StartTask()
		Running = False
		tokenSource = New CancellationTokenSource()
		task = task.Factory.StartNew(AddressOf RunningTask, tokenSource.Token)
	End Sub

	Public Sub StopTask()
		Try
			tokenSource.Cancel()
		Catch ex As Exception

		End Try
	End Sub

	Property Interval As Double
		Get
			Return _Interval
		End Get
		Set(value As Double)
			_Interval = value
			_IntervalTicks = value * stopwatch.Frequency / 1000L
		End Set
	End Property

	Dim error2 As Integer = 0
	Private Sub RunningTask()
		Running = True
		Dim FiveMSTicks As Long = 5L * stopwatch.Frequency / 1000L
		Dim TicksPerMillisecond As Double = stopwatch.Frequency / 1000.0

		Thread.CurrentThread.Priority = ThreadPriority.Highest
		Thread.CurrentThread.Name = "TaskTimer"

		While (Not tokenSource.Token.IsCancellationRequested)
			Dim NextFrameTicks As Long = stopwatch.ElapsedTicks + _IntervalTicks

			Dim performance As Boolean = stopwatch.IsRunning
			Dim freq As Long = stopwatch.Frequency

			Counter += 1
			action()

			Dim Temp As Long = NextFrameTicks - FiveMSTicks

			Do While stopwatch.ElapsedTicks < NextFrameTicks
				If tokenSource.IsCancellationRequested Then
					Return
				End If
				If stopwatch.ElapsedTicks < Temp Then
					Dim temp2 = NextFrameTicks - stopwatch.ElapsedTicks - FiveMSTicks
					If temp2 > 0 Then
						Thread.Sleep(temp2 / TicksPerMillisecond)
					Else
						error2 += 1
					End If
				End If
			Loop
		End While
		stopwatch.Stop()
	End Sub
End Class
